package com.zpark.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.UUID;

/**
 * @PackageName: com.zpark.controller
 * @ClassName: FileController
 * @Description:
 * @author: RZS
 * @date: 2023/4/13  16:40
 */
@Controller
@RequestMapping("/file")
public class FileController {

    // 定义文件上传的类型
    private final String TYPE = "jpg,jpeg,png,gif";
    // 定义文件上传的最大容量
    private final int FILE_MAX_SIZE = 1024 * 1024 * 10;
    // 设置保存路径
    private final String PATH = "C:/WorkAndStudy/IDEAProjects/GMD_SpringMVC/SpringMVC-11-FileUpLoadDownLoad/src/main/webapp/uplaod/";

    @RequestMapping("/test.do")
    public void test(MultipartFile fileName){
        try {
            System.out.println(fileName.getBytes());
            System.out.println(fileName.getContentType());
            System.out.println(fileName.getName());
            System.out.println(fileName.getOriginalFilename());
            System.out.println(fileName.getSize());
            System.out.println(fileName.isEmpty());
        } catch(Exception e) {

        }

    }

    @PostMapping("/upload.do")
    public ModelAndView upload(MultipartFile fileName){
        ModelAndView view = new ModelAndView();

        // 判断文件是否为空
        if (fileName.isEmpty()) {
            // 为空
            view.addObject("msg", "文件上传失败，为选中文件");
            view.setViewName("error");
            return view;
        }

        // 文件不为空
        // 判断文件大小是否合法
        if (fileName.getSize() > FILE_MAX_SIZE) {
            // 大小不合法
            view.addObject("msg", "文件上传失败，文件过大");
            view.setViewName("error");
            return view;
        }
        // 获取文件的原名字  xxxx.jpg.png
        String fName = fileName.getOriginalFilename();
        // 截取文件后缀
        String suffix = fName.substring(fName.lastIndexOf(".") + 1);
        // 判断文件后缀是否符合要求
        if (!TYPE.contains(suffix)) {
            // 文件后缀不合法
            view.addObject("msg", "文件上传失败，文件后缀不合法");
            view.setViewName("error");
            return view;
        }

        // 判断路径是否存在，如果不存在则创建
        File file = new File(PATH);
        if (!file.exists()) {
            // 创建目录
            file.mkdirs();
        }
        // 重新生成文件名字
        String newFileName = UUID.randomUUID().toString();
        // 组合路径
        String filePath = PATH + newFileName + "." + suffix;
        // 将上传文件保存到指定目录
        try {
            fileName.transferTo(new File(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        view.addObject("msg", "文件上传成功：" + filePath);
        view.setViewName("success");
        return view;
    }

    @RequestMapping("/download.do/{filename}/{suffix}")
    public ResponseEntity<byte[]> download(HttpServletRequest request,
                                           @PathVariable("filename") String fileName,
                                           @PathVariable("suffix") String suffix){

        String path = PATH + fileName + "." + suffix;
        //创建该图片的对象
        File file = new File(path);
        //将图片数据读取到字节数组中
        byte[] bytes = new byte[0];
        try {
            bytes = FileUtils.readFileToByteArray(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //创建 HttpHeaders 对象设置响应头信息
        HttpHeaders httpHeaders = new HttpHeaders();
        //设置图片下载的方式和文件名称
        httpHeaders.setContentDispositionFormData("attachment", toUTF8String(fileName + "." + suffix));
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);

    }

    /**
     * 下载保存时中文文件名的字符编码转换方法
     */
    public String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer();
        int len = str.length();
        for (int i = 0; i < len; i++) {
            // 取出字符中的每个字符
            char c = str.charAt(i);
            // Unicode码值为0~255时，不做处理
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else { // 转换 UTF-8 编码
                byte b[];
                try {
                    b = Character.toString(c).getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    b = null;
                }
                // 转换为%HH的字符串形式
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0) {
                        k &= 255;
                    }
                    sb.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return sb.toString();
    }
}
